#include "ui.h"

#include "app/app.h"
#include "hardware/lcd.h"
#include "hardware/motor.h"
#include "hardware/lcd_init.h"
#include "mid/input/input.h"


static UIManager gUIMgr;

void InitUIMgr();
void UpdateUI();
void EnterWindow(eWindow eWin);
void Back();
int OnButtonEventCallback(eButtonID btnID, eButtonEvent btnEvent);

UIManager* GetUIMgr()
{
    if (gUIMgr.Init != InitUIMgr)
    {
        gUIMgr.Init = InitUIMgr;
        gUIMgr.Update = UpdateUI;
        gUIMgr.EnterWindow = EnterWindow;
        gUIMgr.Back = Back;
        gUIMgr.initilized = 0;
        gUIMgr.preWin = NULL;
    }
    return &gUIMgr;
}

void InitUIMgr()
{
    if (gUIMgr.initilized == 1)
        return;

    EnterWindow(eWIN_HOME);
    RegisterButtonEventHandler(OnButtonEventCallback);
    gUIMgr.initilized = 1;
}

void UpdateUI()
{
    if (gUIMgr.initilized == 0)
        return;

    Window *curWin = gUIMgr.winStack[gUIMgr.windowCnt - 1];
    if (curWin != gUIMgr.preWin)
        LCD_Fill(0, 0, LCD_W, LCD_H, BLACK);

    curWin->Update();
    curWin->Render();
    gUIMgr.preWin = curWin;
}

void EnterWindow(eWindow eWin)
{
    Window *win = NULL;
    switch (eWin)
    {
    case eWIN_HOME:
        win = GetMainWindow();
        GetApp()->SwitchMode(eAM_None);
        break;

    case eWIN_FIX_SPEED:
        win = GetFixedSpeedWindow();
        GetApp()->SwitchMode(eAM_FIXED_SPEED);
        break;

    case eWIN_FIX_DISTANCE:
        win = GetFixedDistanceWindow();
        GetApp()->SwitchMode(eAM_FIXED_DISTANCE);
        break;
    }
    StopMotor();

    gUIMgr.winStack[gUIMgr.windowCnt++] = win;
}

void Back()
{
    if (gUIMgr.windowCnt > 1)
    {
        gUIMgr.windowCnt--;
        GetApp()->SwitchMode(eAM_None);
    }
}

int OnButtonEventCallback(eButtonID btnID, eButtonEvent btnEvent)
{
    if (gUIMgr.initilized == 0)
        return 0;

    Window *curWin = gUIMgr.winStack[gUIMgr.windowCnt - 1];
    if (curWin->ProcessInput != NULL)
        return curWin->ProcessInput(btnID, btnEvent);
    return 0;
}